<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>

  <script>
    function Vue(options) {
      // 保存配置中的data对象
      this._data = options.data

      // 对data中所有属性实现数据代理
      this._proxy()
    }

    // Vue.prototype._proxy = function () {
      
    // }
    Vue.prototype = {
      _proxy () {
        // 遍历data对象中的所有属性, 给vm添加相应的同名属性
        // Object.keys({a: 1, b: 2})  返回对象中所有属性名组成的数组  ['a', 'b']
        Object.keys(this._data).forEach(key => {  // msg/msg2
          // 利用defineProperty方法给vm添加属性
          Object.defineProperty(this, key, {
            // 读取data对象中对应的属性值返回
            get () {
              return this._data[key]
            },
            // 将最新的属性值value保存到data对象的同名属性上
            set (value) {
              this._data[key] = value
            }
          })
        })
      }
    }
  </script>
  
  <script>
    const vm = new Vue({
      data: {
        msg: 'abc',
        msg2: 123
      }
    })

    console.log(vm.msg) // 'abc'    // 代理读
    vm.msg = 'aaa' // 代理写
    console.log(vm._data.msg) // aaa  
    console.log(vm)
  </script>
</body>
</html>